package com.aabte.lota.auth.auth.service;

import com.aabte.lota.auth.account.entity.User;
import com.aabte.lota.auth.auth.bean.query.LoginQuery;
import com.aabte.lota.auth.auth.token.JWTTokenResult;
import com.aabte.lota.auth.auth.token.JWTTokenUtils;
import com.aabte.lota.auth.auth.token.payload.PermissionDTO;
import com.aabte.lota.auth.auth.token.payload.RoleDTO;
import com.aabte.lota.auth.auth.token.payload.TokenPayloadDTO;
import com.aabte.lota.auth.common.util.ServletUtils;
import com.google.common.collect.Sets;
import io.jsonwebtoken.Claims;
import javax.annotation.Resource;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Service;

/**
 * @author Daniel
 * @version 1.0
 * @date 2020/4/5
 */
@Service
public class LoginService {

  @Resource private JWTTokenUtils jwtTokenUtils;

  public JWTTokenResult login(LoginQuery loginQuery) {
    String username = loginQuery.getUsername();
    String password = loginQuery.getPassword();

    UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken();
    usernamePasswordToken.setUsername(username);
    usernamePasswordToken.setPassword(password.toCharArray());
    usernamePasswordToken.setHost(ServletUtils.getRemoteHost());

    Subject subject = SecurityUtils.getSubject();
    subject.login(usernamePasswordToken);

    if (subject.isAuthenticated()) {
      // 认证通过
      User user = (User) subject.getPrincipal();
      TokenPayloadDTO tokenPayload = convertTokenPayload(user);
      Claims claims = jwtTokenUtils.createClaims(tokenPayload);
      String token = jwtTokenUtils.generateToken(claims);
      return JWTTokenResult.builder().token(token).tokenPayload(tokenPayload).build();
    } else {
      throw new AuthenticationException(username + " not authenticated");
    }
  }

  private TokenPayloadDTO convertTokenPayload(User user) {

    RoleDTO adminRole = RoleDTO.builder().name("admin").build();
    PermissionDTO adminPermission = PermissionDTO.builder().name("admin").build();

    return TokenPayloadDTO.builder()
        .uid(String.valueOf(user.getId()))
        .username(user.getUsername())
        .roles(Sets.newHashSet(adminRole))
        .permissions(Sets.newHashSet(adminPermission))
        .build();
  }
}
